from PyQt5.QtGui import QPalette, QColor, QFont, QCursor
from PyQt5.QtWidgets import QApplication, QMainWindow, QTextEdit, QMenu, QWidget, QPushButton
from PyQt5.QtCore import QTimer, Qt, QPoint
from PyQt5.QtWidgets import QScrollBar

from settings import SettingsDialog


class SubtitleWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.history = []
        self.transcription = ""
        self.is_dragging = False
        self.setMouseTracking(True)  # 启用鼠标跟踪
        self.is_in_edit_mode = False
        self.is_resizing = False  # 标识是否在调整大小
        self.drag_start_pos = QPoint(0, 0)
        self.is_scrolling = False  # 新增标志，指示用户是否在手动滚动
        self.settings_button = None  # 设置按钮初始为None
        self.initUI()

    def initUI(self):
        self.setWindowFlags(Qt.Tool | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setGeometry(400, 800, 800, 300)

        self.text_edit = QTextEdit(self)
        self.text_edit.setGeometry(0, 0, 800, 300)
        self.text_edit.setReadOnly(True)

        font = QFont("Arial", 16)
        self.text_edit.setFont(font)

        palette = QPalette()
        palette.setColor(QPalette.Base, QColor(0, 0, 0, 150))
        palette.setColor(QPalette.Text, QColor(255, 255, 255))
        self.text_edit.setPalette(palette)

        self.text_edit.setAlignment(Qt.AlignLeft)
        self.text_edit.setWordWrapMode(True)

        self.set_display_mode()

        # 监听滚动条的 valueChanged 信号
        self.text_edit.verticalScrollBar().valueChanged.connect(self.on_scrollbar_value_changed)

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.update_subtitle)
        self.timer.start(500)

        # 初始化滚动计时器
        self.scroll_timer = QTimer(self)
        self.scroll_timer.setSingleShot(True)
        self.scroll_timer.timeout.connect(self.resume_auto_refresh)

        # 添加设置按钮，初始隐藏
        self.settings_button = QPushButton('⚙', self)
        self.settings_button.setVisible(False)  # 初始隐藏
        self.settings_button.clicked.connect(self.show_settings_menu)
        self.update_settings_button_position()

    def update_settings_button_position(self):
        """根据窗口大小更新设置按钮的位置"""
        if self.settings_button:
            btn_size = 30  # 按钮的宽高
            self.settings_button.setGeometry(self.width() - btn_size - 10, 10, btn_size, btn_size)

    def resizeEvent(self, event):
        """在窗口大小改变时，更新按钮位置"""
        self.text_edit.setGeometry(0, 0, self.width(), self.height())
        self.update_settings_button_position()  # 调整按钮位置
        super().resizeEvent(event)

    def on_scrollbar_value_changed(self):
        scrollbar = self.text_edit.verticalScrollBar()
        # 当滚动条不在底部时，说明用户正在手动滚动
        if scrollbar.value() != scrollbar.maximum():
            self.is_scrolling = True
            # 暂停实时字幕刷新
            self.timer.stop()
            # 重置计时器，每次用户滚动时都重新开始5秒倒计时
            self.scroll_timer.start(5000)
        else:
            self.is_scrolling = False
            self.scroll_timer.start(500)

    def show_settings_menu(self):
        """显示设置菜单"""
        menu = QMenu(self)

        # 添加菜单选项
        toggle_mode_action = menu.addAction("切换模式")
        toggle_mode_action.triggered.connect(self.toggle_mode)

        # 添加设置选项
        settings_action = menu.addAction("设置背景透明度")
        settings_action.triggered.connect(self.open_settings_dialog)

        # 显示菜单
        menu.exec_(self.settings_button.mapToGlobal(self.settings_button.rect().bottomLeft()))

    def open_settings_dialog(self):
        self.settings_dialog = SettingsDialog(self)
        self.settings_dialog.show()

    def toggle_mode(self):
        # 切换展示模式和编辑模式
        if self.is_in_edit_mode:
            self.set_display_mode()
        else:
            self.set_edit_mode()

    def resume_auto_refresh(self):
        # 滚动条自动滚动到底部
        scrollbar = self.text_edit.verticalScrollBar()
        scrollbar.setValue(scrollbar.maximum())  # 强制滚动条到最底部
        # 恢复字幕的实时刷新
        self.timer.start(500)

    def set_display_mode(self):
        """展示模式"""
        self.text_edit.setTextInteractionFlags(Qt.NoTextInteraction)
        self.setCursor(QCursor(Qt.ArrowCursor))
        self.is_in_edit_mode = False
        if self.settings_button:  # 仅当按钮已初始化时设置可见性
            self.settings_button.setVisible(False)
        self.text_edit.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

    def set_edit_mode(self):
        """编辑模式"""
        self.text_edit.setTextInteractionFlags(Qt.TextSelectableByMouse)
        self.setCursor(QCursor(Qt.IBeamCursor))
        self.is_in_edit_mode = True
        self.settings_button.setVisible(True)  # 显示设置按钮
        self.update_settings_button_position()  # 确保按钮位置正确
        self.text_edit.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)

    def update_subtitle(self):
        # 获取滚动条对象
        scrollbar: QScrollBar = self.text_edit.verticalScrollBar()

        # 如果滚动条在最底部，允许自动滚动
        is_at_bottom = scrollbar.value() == scrollbar.maximum()

        # 构建所有历史字幕的文本
        history_text = "\n".join(self.history)

        # 更新显示：保留历史部分并实时显示当前的句子
        if self.transcription:
            # 用历史字幕加上当前部分实时结果进行显示
            self.text_edit.setPlainText(f"{history_text}\n{self.transcription}")
        elif self.history and self.history[-1] != self.transcription:
            # 如果是完整句子，到达时才更新历史
            self.text_edit.setPlainText(history_text)

        # 如果滚动条在最底部，保持自动滚动
        if is_at_bottom:
            scrollbar.setValue(scrollbar.maximum())

    def resizeEvent(self, event):
        self.text_edit.setGeometry(0, 0, self.width(), self.height())
        super().resizeEvent(event)

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            rect = self.rect()
            pos = event.pos()
            margin = 40  # 扩大边缘检测范围

            if rect.right() - margin <= pos.x() <= rect.right():
                if rect.bottom() - margin <= pos.y() <= rect.bottom():
                    self.is_resizing = "bottom_right"
                    self.drag_start_pos = event.globalPos()
                    self.setCursor(QCursor(Qt.SizeFDiagCursor))
                else:
                    self.is_resizing = "right"
                    self.drag_start_pos = event.globalPos()
                    self.setCursor(QCursor(Qt.SizeHorCursor))
            elif rect.bottom() - margin <= pos.y() <= rect.bottom():
                self.is_resizing = "bottom"
                self.drag_start_pos = event.globalPos()
                self.setCursor(QCursor(Qt.SizeVerCursor))
            else:
                self.is_dragging = True
                self.drag_start_pos = event.globalPos() - self.frameGeometry().topLeft()
                self.setCursor(QCursor(Qt.OpenHandCursor))
            event.accept()

            # 当鼠标按下时，用户开始滚动，标记正在滚动状态
            if self.text_edit.verticalScrollBar().isVisible():
                self.is_scrolling = True

    def mouseMoveEvent(self, event):
        rect = self.rect()
        pos = event.pos()
        margin = 40  # 边缘检测范围

        if self.is_dragging:
            self.move(event.globalPos() - self.drag_start_pos)
            event.accept()
        elif self.is_resizing:
            if self.is_resizing == "right":
                new_width = event.globalPos().x() - self.frameGeometry().x()
                if new_width > 200:
                    self.resize(new_width, self.height())
                self.setCursor(QCursor(Qt.SizeHorCursor))
            elif self.is_resizing == "bottom":
                new_height = event.globalPos().y() - self.frameGeometry().y()
                if new_height > 150:
                    self.resize(self.width(), new_height)
                self.setCursor(QCursor(Qt.SizeVerCursor))
            elif self.is_resizing == "bottom_right":
                new_width = event.globalPos().x() - self.frameGeometry().x()
                new_height = event.globalPos().y() - self.frameGeometry().y()
                if new_width > 200 and new_height > 150:
                    self.resize(new_width, new_height)
                self.setCursor(QCursor(Qt.SizeFDiagCursor))
            event.accept()
        else:
            # 根据鼠标位置判断是否靠近边缘并改变光标样式
            if rect.right() - margin <= pos.x() <= rect.right():
                if rect.bottom() - margin <= pos.y() <= rect.bottom():
                    self.setCursor(QCursor(Qt.SizeFDiagCursor))
                else:
                    self.setCursor(QCursor(Qt.SizeHorCursor))
            elif rect.bottom() - margin <= pos.y() <= rect.bottom():
                self.setCursor(QCursor(Qt.SizeVerCursor))
            else:
                self.setCursor(QCursor(Qt.ArrowCursor))

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.is_dragging = False
            self.is_resizing = False
            self.setCursor(QCursor(Qt.ArrowCursor))
            event.accept()

            # 当鼠标释放时，用户结束滚动，取消滚动状态
            self.is_scrolling = False

    def mouseDoubleClickEvent(self, event):
        if not self.is_in_edit_mode:
            self.set_edit_mode()
        event.accept()

    def focusOutEvent(self, event):
        if self.is_in_edit_mode:
            self.set_display_mode()
        super().focusOutEvent(event)

    def keyPressEvent(self, event):
        if self.is_in_edit_mode and event.key() == Qt.Key_Escape:
            self.set_display_mode()
            self.setCursor(QCursor(Qt.ArrowCursor))
            event.accept()
